Opravneni procesu
Otázka od: Milan Tomes
8. 11. 2004 16:18
Zdravim vsechny,
mam takovy orisek - potrebuji zjistit zda ma proces opravneni pro
cteni/zapis do konkretni vetve registru (standardne HKEY_USERS\.Default, ale
i jinych napr. HKEY_LOCAL_MACHINE apod...) a take do konkretniho adresare na
disku (typicky Program files a dalsich...)...
Diky moc za odpovedi
S pozdravem
Milan Tomes
Odpovedá: Jiri Cincura
8. 11. 2004 20:04
Milan Tomes wrote:
> ale i jinych napr. HKEY_LOCAL_MACHINE apod...) a take do konkretniho
> adresare na disku (typicky Program files a dalsich...)...
Nevim, jak to zjistit, ale co to zkusit a kdyztak chytit exception? Je to
trochu pokulhavajici, ale pro zacatek to muze fungovat.
--
Jiri Cincura
e-mail: mailto:jiri@cincura.net; | http://www.cincura.net/
mailto:xcincura@informatics.muni.cz | http://photo.cincura.net/
ICQ: 314711544 | http://phorum.cincura.net/
---
And if our times are difficult and perplexing,
so are they challenging and filled with opportunity.
-Robert F. Kennedy, 1961
Odpovedá: Milan Tomes
9. 11. 2004 7:26
Tohle reseni me samozrejme napadlo, ale nejak se mi do nej nechce... Rad
bych spise zjistil, zda existuje opravneni na zaklade pristupovych prav
uzivatele, pod kterym bezi dany proces bez pouziti metody try - except...
S pozdravem
Milan Tomes
> [mailto:delphi-l-owner@clexpert.cz]On Behalf Of Jiri Cincura
> Sent: Monday, November 08, 2004 8:04 PM
>
> Milan Tomes wrote:
> > ale i jinych napr. HKEY_LOCAL_MACHINE apod...) a take do konkretniho
> > adresare na disku (typicky Program files a dalsich...)...
>
> Nevim, jak to zjistit, ale co to zkusit a kdyztak chytit exception? Je to
> trochu pokulhavajici, ale pro zacatek to muze fungovat.
Odpovedá: Milan Tomes
9. 11. 2004 19:17
Trosku jsem na tom dneska pracoval a vysel mi zatim takovyto kod:
function DirCanWrite(ADir: string): boolean;
var
pTrust: PTRUSTEEA;
SD: Pointer;
RV: DWORD;
Access: Cardinal;
DACL: PACL;
HaveToken: boolean;
Token: THandle;
Count: DWORD;
TokenInfo: PTokenUser;
UserSid: PSid;
User, Domain: string;
begin
Result := false;
UserSid := nil;
if isWinNT then
begin
try
HaveToken := false;
try
TokenInfo := nil;
HaveToken := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
Token);
if GetTokenInformation(Token, TokenUser, nil, 0, Count) or
(GetLastError <> ERROR_INSUFFICIENT_BUFFER) then
RaiseLastOSError;
TokenInfo := PTokenUser(AllocMem(Count));
Win32Check(GetTokenInformation(Token, TokenUser, TokenInfo, Count,
Count));
UserSid := AllocMem(GetLengthSid(TokenInfo^.User.Sid));
CopySid(GetLengthSid(TokenInfo^.User.Sid), UserSid,
TokenInfo^.User.Sid);
finally
if TokenInfo <> nil then
FreeMem(TokenInfo);
if HaveToken then
CloseHandle(Token);
end;
RV := GetNamedSecurityInfo(PChar(ADir), SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION, nil, nil, @DACL, nil, SD);
try
if RV <> ERROR_SUCCESS then
raise
EG3CoreError.CreateFmt('Nastala chyba poi zjis?ovani
poistupovych prav k objektu '
+ ADir + ' (GetNamedSecurityInfo, kod chyby:
%d) !!!', [RV])
else
begin
if DACL = nil then
//NULL DACL - neni povoleno
raise
EG3OSError.Create('Nastala chyba poi zjis?ovani
poistupovych prav k objektu '
+ ADir + ' (GetNamedSecurityInfo - Dacl = nil)
!!!');
pTrust := AllocMem(SizeOf(_TRUSTEE_A));
try
BuildTrusteeWithNameA(pTrust, UserSid);
// pTrust^.pMultipleTrustee := nil;
// pTrust^.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
// pTrust^.TrusteeForm := TRUSTEE_IS_SID;
// pTrust^.TrusteeType := TRUSTEE_IS_USER;
// pTrust^.ptstrName := UserSid;
// if IsValidSid(pTrust^.ptstrName) then
// LookupAccountBySid(pTrust^.ptstrName, User, Domain)
// else
// User := pTrust^.ptstrName;
RV := GetEffectiveRightsFromAclA(DACL^, pTrust^, Access);
if RV <> ERROR_SUCCESS then
raise
EG3CoreError.CreateFmt('Nastala chyba poi zjis?ovani
poistupovych prav k objektu '
+ ADir + ' (GetEffectiveRightsFromAcl, kod
chyby: %d) !!!', [RV]);
Result := (Access and GENERIC_WRITE) = GENERIC_WRITE;
finally
FreeMem(pTrust);
end;
end;
finally
if SD <> nil then
LocalFree(Cardinal(SD));
end;
finally
if UserSid <> nil then
FreeMem(UserSid);
end;
end
else
Result := true;
end;
Tato konstrustrukce funguje az na jednu malickost - pri volani
FreeMem(pTrust) to spadne na Invalid pointer operation.
Pokud misto volani BuildTrusteeWithNameA pouziju prime prirazeni do
struktury pTrust, tak se vyjimka nevyvola, ale kod nefunguje resp. volani
GetEffectiveRightsFromAclA skonci chybou 1337 - Security ID is invalid. SID
je ale spravne - mozno overit volanim IsValidSid.
Pokud upravim datovy typ promenne pTrust na _TRUSTEE_A, zrusim dereference a
u volani BuildTrusteeWithNameA naopak referuji (@pTrust), tak se mi
pravdepodobne prepisuje pamet, protoze pred volanim teto funkce je UserSid
spravne a po navratu je nil.
Absolutne nevim co s tim - pokud ma nekdo tuseni co s tim, tak mu budu
opravdu zauzlovan.
Cil tehle funkce je vraceni boolean hodnoty, zda je do specifikovaneho
adresare mozno cokoliv zapsat - uzivatelska prava. Vim, ze to mohu udelat
ofenzivni metodou, ale ja radsi otestuji, jestli to prava umoznuji a teprve
potom budu neco delat.
S pozdravem
Milan Tomes
Odpovedá: Jakub Cermak
9. 11. 2004 20:09
Zkus misto pTrust := AllocMem(SizeOf(_TRUSTEE_A));
dat GetMem (vetsinou mi FreeMem selhalo pokud se pamet nealokovala pres
Getmem, hlasilo to invalid pointer operation). Ale je to bez zaruky
Jakub Cermak
ja.cermi@centrum.cz
Odpovedá: Milan Tomes
9. 11. 2004 20:54
Ani GetMem neprojde spravne. Zkousel jsem New - Dispose, GetMem/AllocMem -
FreeMem a nic. Problem nastane teprve v okamziku, kdy ten ukazatel predam
funkci BuildTrusteeWithName. Kdyz toto volani zrusim, tak je vse - vcetne
dealokace v poradku...
S pozdravem
Milan Tomes
> [mailto:delphi-l-owner@clexpert.cz]On Behalf Of Jakub Cermak
> Sent: Tuesday, November 09, 2004 8:09 PM
>
> Zkus misto pTrust := AllocMem(SizeOf(_TRUSTEE_A));
> dat GetMem (vetsinou mi FreeMem selhalo pokud se pamet nealokovala pres
> Getmem, hlasilo to invalid pointer operation). Ale je to bez zaruky